#include "log.h"

extern int fputc(int ch, FILE *f);
static uint8_t debug_buf[256];
static char    nibble2char[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
                                   '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};


__WEAK void bs_writer_print_buffer(char *buf, uint32_t len)
{
    FILE *fp = NULL;
    while(len-- > 0) {
        fputc(*buf++, fp);
    }
}


uint32_t bs_writer_print(char *fmt, ...)
{
    uint32_t len, res;
    va_list args;
    char *p=(char *)debug_buf;

    res = 0;
    va_start(args, fmt);
    len = vsnprintf(p, sizeof(debug_buf), fmt, args);
    if (len > sizeof(debug_buf)) {
        res = 1;
    }
    va_end(args);
    
    bs_writer_print_buffer(p, len);

    return res;
}


void bs_writer_print_hexdump(void *buf, int len)
{
    unsigned char *line;
    int i, thisline, offset;
    char* tbl = nibble2char;
    char* p;

    line = (unsigned char *)buf;
    offset = 0;

    while (offset < len) {
        p=(char *)debug_buf;
        *p++ = tbl[(offset >> 12) & 0x0F];
        *p++ = tbl[(offset >> 8)  & 0x0F];
        *p++ = tbl[(offset >> 4)  & 0x0F];
        *p++ = tbl[(offset)       & 0x0F];
        *p++ = ' ';

        thisline = len - offset;
        if (thisline > 16) {
            thisline = 16;
        }

        for (i = 0; i < thisline; i++) {
            *p++ = tbl[line[i]>>4 & 0x0F];
            *p++ = tbl[line[i]    & 0x0F];
            *p++ = ' ';
        }

        for (; i < 16; i++) {
            *p++ = ' ';
            *p++ = ' ';
            *p++ = ' ';
        }

        for (i = 0; i < thisline; i++) {
            if ((line[i] >= 0x20 && line[i] < 0x7f))
                *p++ = line[i];
            else
                *p++ = '.';
        }

        *p++ = '\r';
        *p++ = '\n';
        offset += thisline;
        line += thisline;
        bs_writer_print_buffer(debug_buf, 5+16*3+ thisline +2);
    }
}


#define DEBUG_IDLE      0
#define DEBUG_BUSY      1
#define DEBUG_EROR      2

static uint8_t debug_dam_buf[128];

void bs_writer_print_buffer(char *buf, uint32_t len)
{
    // 先把数据保存到队列中
    kfifo_put(buf, len);
    if (ut.state == DEBUG_BUSY && bs_jiffiles > ut.timeout) {
        // 尝试重启：重新配置
        bs_writer_debug_init();
    }
    if (ut.state == DEBUG_IDLE) {
        // 启动一次传输
        bs_writer_debug_send();
        ut.state == DEBUG_BUSY;
    }
}



void bs_writer_debug_init()
{
    // 配置 dma，传输中断
}

void bs_writer_debug_deinit()
{
    // 释放IO、DMA
}

void bs_writer_debug_reset()
{
    // 重置缓冲区，清标志
}


void bs_writer_debug_send()
{
    // 启动一次dma
}

void bs_writer_debug_isr()
{
    // 传输完成中断
    if (kfifo_len() > 0) {
        kfifo_get(debug_dam_buf, 128);
        bs_writer_debug_send();
    } else {
        // 关闭中断、关闭dma
    }
}